package de.toolschmied.jjas.client.widgets;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;

import de.toolschmied.jjas.client.cms.actions.Alignment;
import de.toolschmied.jjas.client.cms.actions.AlignmentAction.AlignmentListener;
import de.toolschmied.jjas.client.cms.actions.AlignmentToolbar;
import de.toolschmied.jjas.client.cms.actions.EditingToolbar;
import de.toolschmied.jjas.client.cms.actions.EditingToolbar.EditingListener;
import de.toolschmied.jjas.client.cms.actions.HeadingType;
import de.toolschmied.jjas.client.cms.actions.HeadingTypeAction.HeadingTypeListener;
import de.toolschmied.jjas.client.cms.actions.HeadingTypeToolbar;
import de.toolschmied.jjas.client.widgets.toolbar.PopupToolbar;


public class EditableHeading extends SimplePanel {

	private final MouseClickHandler clickHandler = new MouseClickHandler();
	private final KeyHandler keyHandler = new KeyHandler();
	private final Toolbar toolbar = new Toolbar();
	
	private final HTML html = new HTML();
	private final TextBox textBox = new TextBox();
	
	private HeadingType type;
	private String text;
	private Alignment alignment;
	
	public EditableHeading(HeadingType type, Alignment alignment, String text) {
		super();
		
		setAlignment(alignment);
		setHeadingType(type);
		setText(text);
		
		html.addClickHandler(clickHandler);
		textBox.addKeyPressHandler(keyHandler);

		setWidget(html);
	}

	private void setAlignment(Alignment alignment) {
		this.alignment = alignment;
		textBox.setAlignment(alignment.textAlignment);
		getElement().getStyle().setTextAlign(alignment.textAlign);
	}
	
	private void setText(String text) {
		this.text = text;
		updateLabel();
	}

	private void setHeadingType(HeadingType type) {
		this.type = type;
		String styleName = "input-" + type.getElementName();
		textBox.setStylePrimaryName(styleName);
		html.setStylePrimaryName(styleName);
		updateLabel();
	}

	private void updateLabel() {
		String labelText = "<" + type + ">" + text + "</" + type + ">";
		html.setHTML(labelText);
	}

	private void startEditing() {
		textBox.setText(text);
		textBox.setWidth(html.getOffsetWidth() + "px");
		setWidget(textBox);
		textBox.setFocus(true);
		textBox.selectAll();
		showPopupToolbar();
	}
	
	private void showPopupToolbar() {
		toolbar.setSelection(type, alignment);
		toolbar.showBelow(this);
	}
	
	private void saveEditing() {
		String updateText = textBox.getText();
		setText(updateText);
		setWidget(html);
		hidePopupToolbar();
	}

	private void cancelEditing() {
		setWidget(html);
		hidePopupToolbar();
	}
	
	private void hidePopupToolbar() {
		toolbar.hide();
	}
	
	private class MouseClickHandler implements ClickHandler {

		@Override
		public void onClick(ClickEvent event) {
			Log.debug("Mouse Clicked");
			startEditing();
		}
		
	}
	
	private class KeyHandler implements KeyPressHandler {

		@Override
		public void onKeyPress(KeyPressEvent event) {
			int keyCode = event.getNativeEvent().getKeyCode();
			if (keyCode == KeyCodes.KEY_ENTER) {
				event.stopPropagation();
				saveEditing();
			}
			else if (keyCode == KeyCodes.KEY_ESCAPE) {
				event.stopPropagation();
				cancelEditing();
			}
		}
		
	}
	
	private class Toolbar extends PopupToolbar implements AlignmentListener, EditingListener, HeadingTypeListener {

		private final HeadingTypeToolbar headingToolbar = new HeadingTypeToolbar(this);
		private final AlignmentToolbar alignmentToolbar = new AlignmentToolbar(this);
		private final EditingToolbar editingToolbar = new EditingToolbar(this);
		
		private Toolbar() {
			addToolbar(headingToolbar);
			addToolbar(alignmentToolbar);
			addToolbar(editingToolbar);
		}

		public void setSelection(HeadingType type, Alignment alignment) {
			headingToolbar.setSelected(type);
			alignmentToolbar.setSelection(alignment);
		}
		
		@Override
		public void saveEditing() {
			EditableHeading.this.saveEditing();
		}

		@Override
		public void cancelEditing() {
			EditableHeading.this.cancelEditing();
		}

		@Override
		public void alignmentChanged(Alignment alignment) {
			setAlignment(alignment);
		}

		@Override
		public void headingTypeChanged(HeadingType headingType) {
			setHeadingType(headingType);
		}
	}

}
